package service

import (
	middleware "antiquity_map/internal/middlewares"
	repository "antiquity_map/internal/repositories"
	customerrors "antiquity_map/pkgs/errors"
	"antiquity_map/pkgs/utils"
	"errors"

	"github.com/golang-jwt/jwt/v5"
	"github.com/spf13/viper"
	"gorm.io/gorm"
)

type UserService interface {
	// Define the methods that UserService should have
	Login(username, password string, jwtMiddlerware middleware.IJWTMiddleware) (string, string, bool, error)
	RefreshToken(refreshToken string, jwtMiddleware middleware.IJWTMiddleware) (string, string, error)
	Signup(account, email, nickname, password, phone string) error
	UpdateUserInfo(account string, updates map[string]interface{}) error
	Logout(account string, jwtMiddlerware middleware.IJWTMiddleware) error
}

type userService struct {
	userRepo repository.UserRepository
}

func NewUserService(userRepo repository.UserRepository, jwtMiddleware middleware.IJWTMiddleware) UserService {
	return &userService{
		userRepo: userRepo,
	}
}

func (s *userService) Login(username, password string, jwtMiddlerware middleware.IJWTMiddleware) (string, string, bool, error) {

	password, salt, err := s.userRepo.GetPasswordAndSaltByUsername(username)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return "", "", false, &customerrors.UserNotFoundError{Username: username}
		}
		return "", "", false, err
	}
	// 验证密码
	saltedPassword, err := utils.HashPassword(password, salt)
	if err != nil {
		return "", "", false, err
	}
	verify, err := utils.VerifyPassword(password, saltedPassword)
	if err != nil {
		return "", "", false, err
	}
	// 验证失败
	if verify != true {
		return "", "", false, &customerrors.UserPasswordError{Username: username}
	}
	// 验证成功
	//查询身份
	identity, err := s.userRepo.GetUserIdentity(username)
	var role string
	if identity == 0 {
		role = "user"
	} else {
		role = "reviewer"
	}
	// 生成令牌对

	tokenPair, err := jwtMiddlerware.GenerateTokenPair(username, role)
	return tokenPair.AccessToken, tokenPair.RefreshToken, true, nil
}

// RefreshToken 刷新令牌
func (s *userService) RefreshToken(refreshToken string, jwtMiddleware middleware.IJWTMiddleware) (string, string, error) {
	// 获取JWT密钥
	secretKey := viper.GetString("jwt.secret_key")
	if secretKey == "" {
		return "", "", errors.New("JWT secret key is not set")
	}
	// 解析刷新令牌
	claims := &middleware.Claims{}
	parsedToken, err := jwt.ParseWithClaims(refreshToken, claims, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, errors.New("unexpected signing method")
		}
		return []byte(secretKey), nil
	})

	if err != nil {
		return "", "", err
	}
	_ = parsedToken
	// 查询身份
	identity, err := s.userRepo.GetUserIdentity(claims.UserID)
	var role string
	if identity == 0 {
		role = "user"
	} else {
		role = "reviewer"
	}
	// 刷新令牌
	tokenPair, err := jwtMiddleware.RefreshToken(refreshToken, role)
	if err != nil {
		return "", "", err
	}

	return tokenPair.AccessToken, tokenPair.RefreshToken, nil
}

func (s *userService) Signup(account, email, nickname, password, phone string) error {
	// 生成盐
	salt, err := utils.GenerateSalt()
	if err != nil {
		return err
	}
	// 计算哈希
	saltedPassword, err := utils.HashPassword(password, salt)
	if err != nil {
		return err
	}
	// 保存用户
	err = s.userRepo.CreateUser(account, email, nickname, saltedPassword, salt, phone)
	if err != nil {
		return err
	}
	return nil
}

func (s *userService) UpdateUserInfo(account string, updates map[string]interface{}) error {
	// 更新密码时，重新生成盐值和加密密码
	if password, ok := updates["password"]; ok {
		salt, err := utils.GenerateSalt()
		if err != nil {
			return err
		}
		saltedPassword, err := utils.HashPassword(password.(string), salt)
		if err != nil {
			return err
		}

		updates["salt"] = salt
		updates["salted_password"] = saltedPassword
		// 删除原始密码，不直接存储
		delete(updates, "password")
	}
	return s.userRepo.UpdateUserInfo(account, updates)
}

func (s *userService) Logout(account string, jwtMiddleware middleware.IJWTMiddleware) error {
	return jwtMiddleware.InvalidateTokens(account)
}
